package com.imooc.classloader;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName ManagerFactory
 * @Description TODO
 * @Author Wxg
 * @Date 2018/11/15 1:16
 * @Version 1.0
 */
public class ManagerFactory {

    private static final Map<String,LoadInfo> loadTimeMap = new HashMap<>();

    public static final String CLASS_PATH = "F:\\wxg103\\WeekStudy\\WeekStudy\\target\\classes\\";

    public static final String MY_MANAGER = "com.imooc.classloader.impl.MyManager";

    public static BaseManager getManager(String className) {
        File loadFile = new File(CLASS_PATH + className.replace("\\.", "/") + ".class");
        long lastModified = loadFile.lastModified();

        if (loadTimeMap.get(className) == null ||
                loadTimeMap.get(className).getLoadTime() != lastModified) {
            load(className, lastModified);
        }

        return loadTimeMap.get(className).getManager();
    }

    private static void load(String className, long lastModified) {
        MyClassLoader myClassLoader = new MyClassLoader(CLASS_PATH);
        Class<?> loadClass = null;
        try {
            loadClass = myClassLoader.loadClass(className);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        BaseManager manager = newInstance(loadClass);

        LoadInfo loadInfo = new LoadInfo(myClassLoader, lastModified);
        loadInfo.setManager(manager);
        loadTimeMap.put(className, loadInfo);
    }

    private static BaseManager newInstance(Class<?> loadClass) {
        try {
            return (BaseManager)loadClass.getConstructor(new Class[]{}).newInstance(new Object[]{});
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        return null;
    }

}
